package com.jinrustar.serialporttest

import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.View
import android.widget.*
import com.jinrustar.shenjiying.core.support.BaseActivity
import java.lang.ref.WeakReference


class MainActivity : BaseActivity() {

    lateinit var devicesSpinner: Spinner
    lateinit var devicesSpinner2: Spinner

    lateinit var baudRatesSpinner: Spinner
    lateinit var baudRatesSpinner2: Spinner

    lateinit var mReceivedEditText: EditText

    lateinit var mSendEditText: EditText

    lateinit var mSendButton: Button

    private lateinit var mDevicePath: String
    private var mCurrentBaudRate: Int = 0


    private lateinit var mDevicePath2: String
    private var mCurrentBaudRate2: Int = 0

    private lateinit var mHandler: Handler

    private var serialPortUtilForSpliter: SerialPortUtil? = null/*5进1出*/
    private var serialPortUtilForUsbPower: SerialPortUtil? = null/*usb电源*/

    override fun getContentViewId(): Int {
        return R.layout.activity_main
    }

    override fun initAllMembersView(savedInstanceState: Bundle?) {
        initAll()
    }

    private fun initAll() {
        devicesSpinner = findViewById(R.id.spinner_devices)
        devicesSpinner2 = findViewById(R.id.spinner_devices2)
        baudRatesSpinner = findViewById(R.id.spinner_baud_rates)
        baudRatesSpinner2 = findViewById(R.id.spinner_baud_rates2)
        mReceivedEditText = findViewById(R.id.et_received)
        mSendEditText = findViewById(R.id.et_send)
        mSendButton = findViewById(R.id.btn_send)

        mHandler = ForLeakHandler(WeakReference(this))

        /*所有设备*/
        val sf = SerialPortFinder()

        val allDevicesPath = sf.allDevicesPath
        devicesSpinner.adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, allDevicesPath)
        devicesSpinner2.adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, allDevicesPath)


        /*所有波特率*/
        val allBaudRates = sf.allBaudRates
        baudRatesSpinner.adapter = ArrayAdapter<Int>(this, android.R.layout.simple_spinner_item, allBaudRates)
        baudRatesSpinner2.adapter = ArrayAdapter<Int>(this, android.R.layout.simple_spinner_item, allBaudRates)

        devicesSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

            override fun onNothingSelected(parent: AdapterView<*>?) {
            }

            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                mDevicePath = allDevicesPath[position]
                openSerialPortForSpliter()
            }
        }


        devicesSpinner2.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

            override fun onNothingSelected(parent: AdapterView<*>?) {
            }

            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                mDevicePath2 = allDevicesPath[position]
                openSerialPortForUsbPower()
            }
        }



        baudRatesSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) {
            }

            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                mCurrentBaudRate = allBaudRates[position]
                openSerialPortForSpliter()
            }
        }

        baudRatesSpinner2.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) {
            }

            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                mCurrentBaudRate2 = allBaudRates[position]
                openSerialPortForUsbPower()
            }
        }

        mSendButton.setOnClickListener {
            if (TextUtils.isEmpty(mSendEditText.text)) {
                sendCmdForSpliter()
                sendCmdForUsbPower()
            } else {
                serialPortUtilForSpliter?.sendBuffer(mSendEditText.text.toString().toByteArray())
                serialPortUtilForUsbPower?.sendBuffer(mSendEditText.text.toString().toByteArray())
            }
        }

        mReceivedEditText.movementMethod = ScrollingMovementMethod.getInstance()


        /*默认选中device*/
        devicesSpinner.setSelection(allDevicesPath.indexOf("/dev/ttyS1"))
        /*默认选中波特率*/
        baudRatesSpinner.setSelection(allBaudRates.indexOf(115200))

//        testAllDevices()

        devicesSpinner2.setSelection(allDevicesPath.indexOf("/dev/ttyS4"))
        baudRatesSpinner2.setSelection(allBaudRates.indexOf(9600))
    }


    fun openSerialPortForSpliter() {

//        mHandler.removeMessages(1)

        Log.e(TAG + ",devicePath:", "$mDevicePath->$mCurrentBaudRate")


        serialPortUtilForSpliter?.closeSerialPort()


        serialPortUtilForSpliter = SerialPortUtil(mDevicePath, mCurrentBaudRate)
        serialPortUtilForSpliter?.setOnDataReceiveListener { buffer, size ->

            val dataStr = String(buffer, 0, size)
            Log.e(MainActivity::class.java.simpleName + ",received:", dataStr)

            mHandler.obtainMessage(2, dataStr).sendToTarget()
        }

        sendCmdForSpliter()
    }


    class ForLeakHandler(private var mActivity: WeakReference<MainActivity>) : Handler() {
        override fun handleMessage(msg: Message) {
            val outer = mActivity.get()
            if (outer == null) {
                println("outer is null")
                return
            }
            when (msg.what) {
                1 -> {
                    outer.sendCmdForSpliter()
                }
                2 -> {
                    val data = msg.obj.toString()
                    outer.mReceivedEditText.text.append("spliter -> ").append(data).append("\n")
                    outer.mReceivedEditText.setSelection(outer.mReceivedEditText.text.length, outer.mReceivedEditText.text.length)
                }


                11 -> {
                    outer.sendCmdForUsbPower()
                }
                22 -> {
                    val data = msg.obj.toString()
                    outer.mReceivedEditText.text.append("power -> ").append(data).append("\n")
                    outer.mReceivedEditText.setSelection(outer.mReceivedEditText.text.length, outer.mReceivedEditText.text.length)
                }

            }
        }
    }

    private var currentCmdIndex = 0

    private fun sendCmdForSpliter() {
        val s = arrayOf("port0R", "port1R", "port2R", "port3R", "port4R"/*, "poweronR", "poweroffR"*/)

        currentCmdIndex = (currentCmdIndex + 1) % s.size
        val bytes = s[currentCmdIndex].toByteArray()
        var cmd = s[currentCmdIndex]

        serialPortUtilForSpliter?.sendBuffer(bytes)

        Log.e(TAG + ",send:", "$mDevicePath->$mCurrentBaudRate: $cmd")
        mHandler.sendEmptyMessageDelayed(1, 100)
    }


    fun openSerialPortForUsbPower() {
        serialPortUtilForUsbPower?.closeSerialPort()

        serialPortUtilForUsbPower = SerialPortUtil(mDevicePath2, mCurrentBaudRate2)
        serialPortUtilForUsbPower?.setOnDataReceiveListener { buffer, size ->

            val dataStr = String(buffer, 0, size)
            Log.e(MainActivity::class.java.simpleName + ",received:", dataStr)

            mHandler.obtainMessage(22, dataStr).sendToTarget()
        }

        sendCmdForUsbPower()
    }


    private var currentUsbPowerIndex = 0
    private fun sendCmdForUsbPower() {
        val s = arrayOf(
                "FF 01 01 00", "FF 01 00 00",
                "FF 02 01 00", "FF 02 00 00",
                "FF 03 01 00", "FF 03 00 00",
                "FF 04 01 00", "FF 04 00 00",
                "FF 05 01 00", "FF 05 00 00"
        )
        currentUsbPowerIndex = (currentUsbPowerIndex + 1) % s.size

        val cmd = s[currentUsbPowerIndex]

        serialPortUtilForUsbPower?.sendStr(cmd)
        Log.e(TAG + ",send:", "$mDevicePath2->$mCurrentBaudRate2: $cmd")
        mHandler.sendEmptyMessageDelayed(11, 1000)
    }
}
